package carpediem.xin.tamplate.network;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

import carpediem.xin.tamplate.propertie.APIServiceProp;
import carpediem.xin.tamplate.propertie.CacheProp;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Subscriber;
import timber.log.Timber;

/**
 * Created by zhaijianwei on 16/12/8.
 * retrofit工厂类，封装retrofit、okhttp3和缓存配置，创建服务实例
 */
public class ServiceFactory {

    public static final String TAG = ServiceFactory.class.getSimpleName();
    private final static long DEFAULT_TIMEOUT = 10;//超时时间，单位s
    /*Json解析器配置*/
    private final Gson mGsonProp;

    public ServiceFactory() {
        mGsonProp = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd hh:mm:ss")
                .create();
    }

    public static ServiceFactory getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public Gson getGson() {
        return mGsonProp;
    }

    /**
     * 根据类模版创建接口
     *
     * @param serviceClass 服务的模版定义类
     * @return 相应服务实例
     */
    public <S> S createService(Class<S> serviceClass) {
        return createService(serviceClass, false);
    }

    /**
     * 根据类模版创建接口
     *
     * @param serviceClass            服务的模版定义类
     * @param useAccessTokenAndUserId 可选accessToken&userId，部分接口需要.true:添加UserManager中的accessToken
     * @return 相应服务实例
     */
    public <S> S createService(Class<S> serviceClass, boolean useAccessTokenAndUserId) {
        /*
        * 配置接口服务地址
        * 1.优先在配置的serviceClass类中查找属性BASE_URL的值作为baseUrl;
        * 2.如果无BASE_URL属性，则配置为APIServiceProp.BASE_URL
        * */
        String baseUrl = "";
        try {
            Field fBaseUrl = serviceClass.getField("BASE_URL");
            baseUrl = (String) fBaseUrl.get(serviceClass);
        } catch (NoSuchFieldException e) {
            Timber.tag(TAG).e(serviceClass.getSimpleName() + "'s BASE_URL is not existed. " + e.getMessage());
        } catch (IllegalAccessException e) {
            Timber.tag(TAG).e(serviceClass.getSimpleName() + "'s BASE_URL is not accessed. " + e.getMessage());
        }
        if (TextUtils.isEmpty(baseUrl)) baseUrl = APIServiceProp.BASE_URL;
        /*配置retrofit*/
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(baseUrl + "/")
                .client(getHttpClient(useAccessTokenAndUserId))
                .addConverterFactory(GsonConverterFactory.create(mGsonProp))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create());
        Retrofit retrofit = builder.build();
        return retrofit.create(serviceClass);
    }

    /**
     * 配置http代理，使用okhttp3实现
     *
     * @param useAccessTokenAndUserId true：header中携带accessToken&userId
     */
    private OkHttpClient getHttpClient(boolean useAccessTokenAndUserId) {
        //定制OkHttp
        OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
        //设置超时时间
        okHttpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        okHttpClientBuilder.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        okHttpClientBuilder.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        //设置header添加accessToken
        if (useAccessTokenAndUserId) {
            okHttpClientBuilder.addInterceptor(new HeaderInterceptor());
        }
        //设置缓存
        File okHttpCacheDirectory = CacheProp.getOkHttpCacheDir();
        if (null != okHttpCacheDirectory) {
            okHttpClientBuilder.cache(new Cache(okHttpCacheDirectory, CacheProp.MIN_CACHE_REQUIRE_BYTES));
        }
        okHttpClientBuilder
                .addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        Timber.tag(TAG).d(message);
                    }
                }).setLevel(HttpLoggingInterceptor.Level.BODY));
        return okHttpClientBuilder.build();
    }

    public void test(Subscriber subscriber) {

    }

    private static class SingletonHolder {
        private static final ServiceFactory INSTANCE = new ServiceFactory();
    }

    public class HeaderInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();
            Request.Builder builder = originalRequest.newBuilder();
            //accessToken非空时添加accessToken
//            String headerUserId = UserManager.getInstance().getCachedUserId();
//            String headerAccessToken = UserManager.getInstance().getCachedAccessToken();
//            if (!TextUtils.isEmpty(headerAccessToken)) {
//                builder.addHeader("access_token", headerAccessToken);
//            }
//            if (!TextUtils.isEmpty(headerUserId)) {
//                builder.addHeader("user_id", headerUserId);
//            }
            Request request = builder.addHeader("deviceplatform", "android")
//                    .removeHeader("User-Agent")
//                    .addHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0")
                    .build();
            Response response = chain.proceed(request);
            return response;
        }
    }
}
